package com.wenjh.jdmzt.protocol;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.wenjh.jdmzt.AndroidKit;
import com.wenjh.jdmzt.exception.NetworkUnavailableException;

/**
 * HTTP 协议请求
 */
public class HttpRequester {
	//private static X509HostnameVerifier HOST_NAME_VERIFIER = Configs.IS_IGNORE_CERTIFICATE ? SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER : SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
	
	private static final int TIMEOUT_CONNECTION = 10 * 1000; // 连接超时时间
	private static final int TIMEOUT_READ = 30 * 1000; // 读取超时时间
	
	public static byte[] post(String url, Map<String, String> params, FormFile[] files, Map<String, String> headers) throws Exception {     
        return readStream(postConnection(url, params, files, headers).getInputStream());
	}
	
	/**
	 * 发起Get请求
	 * @param url
	 * @param params
	 * @param header
	 * @return
	 * @throws Exception
	 */
	public static byte[] get(String url, Map<String, String> params, Map<String, String> header) throws Exception {
		Map<String, String> headers2 = new HashMap<String, String>();
		/*headers2.put("User-Agent", AndroidgetUserAgent());
		headers2.put("Accept-Language", "zh-CN");
		//cookie 写入 sessionId
		if(!StringUtils.isEmpty(MomoKit.getCookie())){
			headers2.put(Configs.coo, MomoKit.getCookie());
		}*/
		
		if(header != null) {
			headers2.putAll(header);
		}

		HttpURLConnection conn = requestGet(url, params, headers2);
		
		return readStream(conn.getInputStream());
	}

	/**
	 * 获得Get请求的连接对象
	 * @param url
	 * @param params
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	public static HttpURLConnection requestGet(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
		// append parameter
		if(params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {	
				url = URLProcessUtil.appendParameter(url, entry.getKey(), entry.getValue());
			}
		}
		
		HttpURLConnection conn = getURLConnetion(url);
		
		conn.setConnectTimeout(TIMEOUT_CONNECTION);
		conn.setReadTimeout(TIMEOUT_READ);
		conn.setRequestMethod("GET");
		
		if(headers != null) {
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}
		}
		
		return conn;
	}
	
	/**
	 * 读取流
	 * @param inStream
	 * @return 字节数组
	 * @throws Exception
	 */
	public static byte[] readStream(InputStream inStream) throws Exception{
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while( (len=inStream.read(buffer)) != -1){
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		return outSteam.toByteArray();
	}

	/**
	 * 获得http请求对象，可能走加密通道
	 * @param urlAddress
	 * @return
	 * @throws IOException 
	 */
	private static HttpURLConnection getURLConnetion(String urlAddress) throws Exception {
		URL url = new URL(urlAddress);
		return (HttpURLConnection) url.openConnection();
		
		/*if(url.getProtocol().equals("https")){
		    HttpsURLConnection httpcon = (HttpsURLConnection) url.openConnection();
		    httpcon.setHostnameVerifier(HOST_NAME_VERIFIER);
		    return httpcon;
		}else{
		    return (HttpURLConnection) url.openConnection();
		}*/
	}
	
	/**
	 * 提交请求，请求成功后。
	 * 注意，提交方式默认是POST。如果要特殊需要GET请求的地方，请自行设置：<br>
	 * conn.setDoInput(true);<br>
	 * conn.setRequestMethod("GET");<br>
	 * @param urlString URL地址
	 * @param params 文本参数
	 * @param files 上传的文件对象
	 * @param headers http请求头
	 * @return
	 * @throws Exception
	 */
	public static HttpURLConnection postConnection(String urlString, Map<String, String> params, FormFile[] files,  Map<String, String> headers) throws Exception {
		if (!AndroidKit.isNetworkAvailable()) {
			throw new NetworkUnavailableException();
		}
		
		final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
        final String ENDLINE = "--" + BOUNDARY + "--\r\n";//数据结束标志
        final String CHARSET = "UTF-8";
        
        int fileDataLength = 0;
        if(files != null) {
        	for(FormFile uploadFile : files){//得到文件类型数据的总长度
        		StringBuilder fileExplain = new StringBuilder();
        		fileExplain.append("--");
        		fileExplain.append(BOUNDARY);
        		fileExplain.append("\r\n");
        		fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
        		fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
        		fileExplain.append("\r\n");
        		fileDataLength += fileExplain.length();
        		if(uploadFile.getInStream()!=null){
        			fileDataLength += uploadFile.getFile().length();
        		}else{
        			fileDataLength += uploadFile.getData().length;
        		}
        	}
        }
        
        StringBuilder textEntity = new StringBuilder();
        if(params != null) {
        	for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据
        		textEntity.append("--");
        		textEntity.append(BOUNDARY);
        		textEntity.append("\r\n");
        		textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
        		textEntity.append(entry.getValue());
        		textEntity.append("\r\n");
        	}
        }
        
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength;
        if(dataLength > 0) {
        	dataLength +=  ENDLINE.getBytes().length;
        }
        
        
        HttpURLConnection conn = getURLConnetion(urlString);
        // 设置请求头信息
        conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setConnectTimeout(TIMEOUT_CONNECTION);
		conn.setReadTimeout(TIMEOUT_READ);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Charset", CHARSET);
		conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY);
		conn.setRequestProperty("Content-Length", dataLength+"");
		conn.setRequestProperty("Accept-Language", "zh-CN");

//		conn.setRequestProperty("User-Agent", MomoKit.getUserAgent());
		
		//cookie 写入 sessionId
//		if(!StringUtils.isEmpty(MomoKit.getCookie())){
//			conn.setRequestProperty(Configs.coo, MomoKit.getCookie());
//		}

		if(headers != null) {
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}
		}
		
       
        //把所有文件类型的实体数据发送出来
        if((params != null && !params.isEmpty()) || (files != null && files.length > 0)) {

        	OutputStream outStream = conn.getOutputStream();
        	
        	if(params != null && !params.isEmpty()) {
        		//把所有文本类型的实体数据发送出来
        		outStream.write(textEntity.toString().getBytes());	   
        		outStream.flush();
        	}
	        
        	if(files != null && files.length > 0) {
        		for(FormFile uploadFile : files){
        			StringBuilder fileEntity = new StringBuilder();
        			fileEntity.append("--");
        			fileEntity.append(BOUNDARY);
        			fileEntity.append("\r\n");
        			fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
        			fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
        			outStream.write(fileEntity.toString().getBytes());
        			if(uploadFile.getInStream()!=null){
        				byte[] buffer = new byte[1024];
        				int len = 0;
        				while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){
        					outStream.write(buffer, 0, len);
        				}
        				uploadFile.getInStream().close();
        			}else{
        				outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
        			}
        			outStream.write("\r\n".getBytes());
        		}
        		outStream.flush();
        	}
        	
	        //下面发送数据结束标志，表示数据已经结束
	        outStream.write(ENDLINE.getBytes());
	        outStream.flush();
	        outStream.close();
        }
        
        return conn;
	}
	
	/**
	 * 提交一段二进制数据
	 * @param url
	 * @param bytes
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	public static byte[] postConnection(String url, byte[] bytes, Map<String, String> headers) throws Exception {
		if (!AndroidKit.isNetworkAvailable()) {
			throw new NetworkUnavailableException();
		}
		
		HttpURLConnection conn = getURLConnetion(url);
		conn.setRequestMethod("POST");
		conn.setDoOutput(true);
		conn.setConnectTimeout(TIMEOUT_CONNECTION);
		conn.setReadTimeout(TIMEOUT_READ);
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Charset", "UTF-8");
		/*conn.setRequestProperty("User-Agent", MomoKit.getUserAgent());
		if(!StringUtils.isEmpty(MomoKit.getCookie())){
			conn.setRequestProperty(Configs.coo, MomoKit.getCookie());
		}*/
		
		if(headers != null) {
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}
		}
		
		
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		conn.setRequestProperty("Content-Length", bytes.length+"");
		
		OutputStream outStream = conn.getOutputStream();
		outStream.write(bytes);
		outStream.flush();
		outStream.close();
		
		return readStream(conn.getInputStream());
		
	}
	
}